package service

import (
	"context"
	"fmt"

	pb "bilinadmin/api/pb/server"
	"bilinadmin/internal/dao"
	"bilinadmin/internal/model"
	"bilinadmin/pkg/lueerror"
)

// LoginBilin 登陆比邻
func (srv *empSrv) LoginBilin(ctx context.Context, brandId int64, gId string) (*pb.EmployeeLoginReply, lueerror.LueError) {
	emp, err := dao.GetEmployeeDao().GetEmpByBrandAndAccount(ctx, brandId, gId)
	if err != nil {
		return nil, lueerror.DbErr(err)
	}
	if emp == nil {
		return nil, lueerror.InvalidEmployee(fmt.Errorf("员工不存在"))
	}
	if !emp.IsValid() {
		return nil, lueerror.InvalidEmployee(fmt.Errorf("员工 %d 无法登陆", emp.Id))
	}
	brandOp, storesOp, errL := srv.EmpOperators(ctx, brandId, emp.Id)
	if errL != nil {
		return nil, errL
	}
	ret := &pb.EmployeeLoginReply{
		EmpId:          emp.Id,
		BrandId:        emp.BrandId,
		EmpName:        emp.Name,
		BrandOperator:  brandOp,
		StoreOperators: storesOp,
	}
	return ret, nil
}

func (srv *empSrv) getPermissionRouters(ctx context.Context, perms []*model.RolePermission) ([]string, lueerror.LueError) {
	routers := make([]string, len(perms))
	for idx, perm := range perms {
		// 该查询有进程缓存
		p, err := dao.GetPermissionDao().GetPermissionById(ctx, perm.PerId)
		if err != nil {
			return nil, lueerror.DbErr(err)
		}
		if p != nil {
			routers[idx] = p.Router
		}
	}
	return routers, nil
}

// 品牌运营信息聚合
func (srv *empSrv) brandOperationAgg(ctx context.Context, brandId, empId int64, op *model.Operator) (*pb.BrandOperatorReply, lueerror.LueError) {
	brand, err := dao.GetBrandDao().GetBrandById(ctx, brandId)
	if err != nil {
		return nil, lueerror.DbErr(err)
	}
	if brand == nil {
		return nil, lueerror.InvalidBrand(fmt.Errorf("品牌 %d 不存在", brandId))
	}
	if !brand.IsValid() {
		return nil, nil
	}
	ret := &pb.BrandOperatorReply{
		BrandId:      brand.Id,
		BrandName:    brand.Name,
		BrandLogo:    brand.Logo,
		IsSuperAdmin: brand.SuEmpId == empId,
		Permission:   []string{},
	}
	if op == nil || op.RoleId == 0 {
		return ret, nil
	}
	roleAgg, err := dao.GetRoleDao().GetRoleById(ctx, op.RoleId)
	if err != nil {
		return nil, lueerror.DbErr(err)
	}
	if roleAgg == nil {
		return ret, nil
	}
	ret.RoleId = roleAgg.Role.Id
	ret.RoleName = roleAgg.Role.Name
	ret.IsAdmin = roleAgg.Role.IsAdmin
	perms, errL := srv.getPermissionRouters(ctx, roleAgg.Perms)
	if errL != nil {
		return nil, errL
	}
	ret.Permission = perms
	return ret, nil
}

// 门店运营信息聚合
func (srv *empSrv) storeOperationAgg(ctx context.Context, brandId, storeId, empId int64, op *model.Operator) (*pb.StoreOperatorReply, lueerror.LueError) {
	store, err := dao.GetStoreDao().GetStoreById(ctx, storeId)
	if err != nil {
		return nil, lueerror.DbErr(err)
	}
	if store == nil {
		return nil, lueerror.InvalidStore(fmt.Errorf("门店 %d 不存在", brandId))
	}
	if !store.IsValid() {
		return nil, nil
	}
	ret := &pb.StoreOperatorReply{
		StoreId:      store.Id,
		StoreName:    store.Name,
		IsSuperAdmin: store.SupEmpId == empId,
		Permission:   []string{},
	}
	if op == nil || op.RoleId == 0 {
		return ret, nil
	}
	roleAgg, err := dao.GetRoleDao().GetRoleById(ctx, op.RoleId)
	if err != nil {
		return nil, lueerror.DbErr(err)
	}
	if roleAgg == nil {
		return ret, nil
	}
	ret.RoleId = roleAgg.Role.Id
	ret.RoleName = roleAgg.Role.Name
	ret.IsAdmin = roleAgg.Role.IsAdmin
	perms, errL := srv.getPermissionRouters(ctx, roleAgg.Perms)
	if errL != nil {
		return nil, errL
	}
	ret.Permission = perms
	return ret, nil
}

// EmpOperators 员工运营实体
func (srv *empSrv) EmpOperators(ctx context.Context, brandId, empId int64) (*pb.BrandOperatorReply, []*pb.StoreOperatorReply, lueerror.LueError) {
	// 先获取有效运营角色
	ops, err := dao.GetOperatorDao().GetValidOperatorByEmpId(ctx, brandId, empId)
	if err != nil {
		return nil, nil, lueerror.DbErr(err)
	}
	var errL lueerror.LueError
	brandOp := &pb.BrandOperatorReply{}
	var storeOps []*pb.StoreOperatorReply
	for _, op := range ops {
		switch op.RefType {
		case model.RefTypeBrand:
			brandOp, errL = srv.brandOperationAgg(ctx, brandId, empId, op)
			if errL != nil {
				return nil, nil, errL
			}
		case model.RefTypeStore:
			var storeOp *pb.StoreOperatorReply
			storeOp, errL = srv.storeOperationAgg(ctx, brandId, op.RefId, empId, op)
			if errL != nil {
				return nil, nil, errL
			}
			if storeOp != nil {
				storeOps = append(storeOps, storeOp)
			}
		default:
			continue
		}
	}
	// 如果没有品牌运营角色，判断下是否是超级管理员
	if brandOp.BrandId == 0 {
		brandOp, errL = srv.brandOperationAgg(ctx, brandId, empId, nil)
		if errL != nil {
			return nil, nil, errL
		}
	}
	if len(storeOps) == 0 {
		// 查询门店超级管理员
		supStores, err := dao.GetStoreDao().GetStoresBySupEmpId(ctx, brandId, empId)
		if err != nil {
			return nil, nil, lueerror.DbErr(err)
		}
		for _, ss := range supStores {
			var storeOp *pb.StoreOperatorReply
			storeOp, errL = srv.storeOperationAgg(ctx, brandId, ss.Id, empId, nil)
			if errL != nil {
				return nil, nil, errL
			}
			if storeOp != nil {
				storeOps = append(storeOps, storeOp)
			}
		}
	}
	return brandOp, storeOps, nil
}

func (srv *empSrv) isSuperAdmin(ctx context.Context, brandId, storeId, empId int64) (bool, lueerror.LueError) {
	isSuper := false
	if storeId != 0 {
		// 门店级
		store, err := dao.GetStoreDao().GetStoreById(ctx, storeId)
		if err != nil {
			return false, lueerror.DbErr(err)
		}
		if store == nil || store.BrandId != brandId {
			return false, nil
		}
		isSuper = true
	} else {
		// 品牌级
		brand, err := dao.GetBrandDao().GetBrandById(ctx, brandId)
		if err != nil {
			return false, lueerror.DbErr(err)
		}
		if brand == nil || brand.SuEmpId != empId {
			return false, nil
		}
		isSuper = true
	}
	return isSuper, nil
}

// EmpOperatorInfo 运营对应的角色和权限
func (srv *empSrv) EmpOperatorInfo(ctx context.Context, brandId, storeId, empId int64) (*pb.OperatorInfoReply, lueerror.LueError) {
	op, errL := srv.getOpInfoByEmpId(ctx, empId, brandId, storeId, false)
	if errL != nil {
		return nil, errL
	}
	// 角色不存在，判断是否是超级管理员
	if op == nil {
		isSuper, errL := srv.isSuperAdmin(ctx, brandId, storeId, empId)
		if errL != nil {
			return nil, errL
		}
		roleName := ""
		if isSuper {
			roleName = "超级管理员"
		}
		return &pb.OperatorInfoReply{
			IsSuperAdmin: isSuper,
			RoleId:       0,
			RoleName:     roleName,
			Permission:   []string{},
		}, nil
	}
	roleAgg, err := dao.GetRoleDao().GetRoleById(ctx, op.RoleId)
	if err != nil {
		return nil, lueerror.DbErr(err)
	}
	if roleAgg == nil {
		return nil, lueerror.DirtyData(fmt.Errorf("角色%d 不存在", op.RoleId))
	}
	ret := &pb.OperatorInfoReply{
		IsSuperAdmin: false,
		IsAdmin:      roleAgg.Role.IsAdmin,
		RoleId:       op.RoleId,
		RoleName:     roleAgg.Role.Name,
	}
	routers, errL := srv.getPermissionRouters(ctx, roleAgg.Perms)
	if errL != nil {
		return nil, errL
	}
	ret.Permission = routers
	return ret, nil
}
